/** ******************* smartui2.0 - advance object ************* */
(function() {
	/** ******************* extend object.create ************* */
	typeof(Object.create) !== 'function' && (Object.create = function(proto) {
		var fn = function() {
		};
		fn.prototype = proto;
		return new fn();
	});

	$.mergeObj = function(op, defOp, deep) {
		var obj;
		if (op == null)
			return $.extend(deep, {}, defOp);
			
		$.isEmptyObject(defOp) || $.each(defOp, function(i, n) {
					if (n != null) 
					{
						obj = op[i];
						
						if (obj == null)
							op[i] = n;
						else if(deep && $.isPlainObject(obj))
							$.mergeObj(obj, n,deep);
					}
				});
		return op;
	}

	$.mergeFn = function(fn, mergeFn, before) {
		if (fn) {
			if (mergeFn) {
				return function() {
					before && mergeFn.apply(this, arguments);
					fn.apply(this, arguments);
					before || mergeFn.apply(this, arguments);
				}
			} else
				return fn;
		} else {
			return mergeFn;
		}
	};
	
	/** ******************* baseObject ************* */
	$.IObject = function(name, proto, parent, triggerMode) {
		var args = arguments;
		// name命名参数的方法重载
		if (typeof(name) !== "string") {
			triggerMode = args[2];
			parent = args[1];
			proto = args[0];
			name = null;
		}

		var obj = function() {
			this._indicators = {};
			this.initTrigger && this.initTrigger();
			this.init && this.init.apply(this, arguments);
		};
		// 继承父类
		if (parent) {
			obj.prototype = Object.create(parent.prototype || parent);
			obj.prototype.base = parent.prototype || parent;
			obj.prototype.constructor = obj;
		} else
			obj.prototype.fn = proto;

		obj.fn = obj.prototype;
		// 注册基础类
		$.extend(obj.fn, $.IObject.Base);
		// 是否继承触发器
		triggerMode && $.inherit(obj, $.ITrigger);
		// 重写属性
		proto != null && $.inherit(obj, proto);
		// 标示类型
		obj.fn.__type = 'iobject';
		// 设置对象名
		name && (obj.fn.__name = name);
		return obj;
	}
	// IObject基类方法
	$.IObject.Base = {
		extend : function(prop) {
			$.extend(this, prop);
			return this;
		},
		// 代理方法，统一域与参数控制
		proxy : function(fn, args) {
			if(fn)
			{
				if (!$.isArray(args)) {
					args = Array.prototype.slice.call(arguments, 1);
				}
				return fn.apply(this, args);
			}
		},
		// call方法，指定上下文
		call:function(context,fn,args){
			if(fn)
			{
				if (!$.isArray(args)) {
					args = Array.prototype.slice.call(arguments, 1);
				}
				return fn.apply(context, args);
			}
		},
		//获取父类
		getParent:function(name){
			var parent = this.base,type = this.__name;
			if(type == null && name == null)
				return parent;
			//根据类名进行查找
			while(parent)
			{
				if(name)
				{
					if(name && parent.__name == name)
						return parent;
				}
				else
				{
					if(type != parent.__name)
						return parent;
				}
				
				parent = parent.base;
			}
			return parent;
		},
		//类指针设置/获取方法
		_indicator : function(fnName,indicator){
			if(arguments.length > 1)
				this._indicators[fnName] = indicator;
			else
				return this._indicators[fnName];
		},
		//调用父类方法
		callParent : function(fnName,parentName,args){
			if(!this.base)
				return;
			//参数重载
			if(typeof(parentName) != 'string')
			{
				args = parentName;
				parentName = null;
			}
			var parent,fn,result,indicator = this._indicator(fnName) || this;
			
			parent = parentName ? indicator.getParent(parentName) : (indicator.base || indicator.fn.base || indicator);

			if(parent && (fn = parent[fnName]))
			{
				this._indicator(fnName,parent);
				result = fn.apply(this,args);
			}
			this._indicator(fnName,null);
			return result;
		}
	};
	// 继承方法
	$.inherit = function(obj, prop) {
		$.extend(obj.fn || obj.prototype, prop.prototype || prop);
	}

	/** ******************* adapter ************* */
	// 适配器对象
	var Adapter = $.IObject({
				init : function(mapping, proto, setDefualt, type) {
					this._list = {};
					this.length = 0;
					this.type = type;
					this.base = Adapter.fn;
					// 扩展适配器方法
					proto != null && $.extend(this, proto);
					// 缓存映射对象
					if (mapping) {
						if (type == "copy" || mapping.__type == "iobject")
							this._mapping = mapping;
						else
							this._mapping = $.IObject("base",mapping);
					}
					// 设置默认映射对象
					if(setDefualt)
					{
					this._list.def = this.create()
					}
					//setDefualt && (this._list.def = this.create());
				},
				// 创建对象
				create : function(proto, parent) {
					var obj,mapping;
					if(parent && (parent = this.get(parent, false)))
					{
					  	mapping = parent;
					}
					else
						mapping = this._mapping;

					if (mapping) {
						if (this.type == "copy")
						{
							obj = $.extend(true, {}, mapping, proto);
							obj.base = proto;
						}
						else
						{
							obj = $.IObject(proto, mapping);
							obj = this.type == "object" ? obj : new obj;
						}
					} 
					else
						obj = proto;
						
					return obj;
				},
				// 添加适配器映射对象;
				add:function(type, proto,parent){
					var arrTypes = type.split(","), obj;
						type = arrTypes.shift();
						if(proto)
							proto.__name = type;
						else
							proto = {__name:type};
						
						obj = this._list[type] = this.create(proto,parent);
						if (arrTypes.length) {
							for (var i = 0, len = arrTypes.length; i < len; i++) {
								this._list[arrTypes[i]] = obj;
						}
					}
					this.length++;
					return this;
				},
				remove : function(type){
					var obj = this._list[type];
					if(obj)
					{
						this.length--;
						 this._list[type] = null;
					}
				},
				// 添加适配器映射对象;单项(type, proto,parent),多项(items,parent)
				push : function(type, proto,parent) {
					var self = this;
					if($.isPlainObject(type))
					{
						var items = type;
						parent = proto;
						$.each(items,function(type,op){
							if(op)
							{
								if(op.proto)
									self.add(type,op.proto,op.parent || parent);
								else
									self.add(type,op,parent);
							}
							
						});
					}
					else
						self.add(type, proto,parent);
					return self;
				},
				// 获取适配器映射对象
				get : function(type, defaultMode) {
					var obj = this._list[type];
					if(!obj && defaultMode !== false)
					{
						obj = this.type == "copy" ? $.extend(true,{},this._list.def) : this._list.def;
						
					}
					obj && (obj.type = type);
					return obj;
				},
				setDefault : function(type){
					var obj = this._list[type];
					if(obj)
						this._list.def = obj;
				},
				// 执行适配器映射方法
				fire : function(type) {
					if (this.length) {
						var fn = this.get(type);
						// 当映射器对象为方法时执行
						if ($.type(fn) == 'function') {
							var args = Array.prototype.slice.call(arguments, 1);
							return fn.apply(null, args);
						}
					}
				},
				// 执行适配器映射方法
				fireAll : function(prop) {
					if (this.length && this._list) {
						var args = Array.prototype.slice.call(arguments, 1);
						$.each(this._list, function(type, obj) {
									var fn = prop ? (obj[prop] || obj) : obj;
									// 当映射器对象为方法时执行
									$.type(fn) == 'function' && fn.apply(obj, args);
								})
					}
				}
			})
	// 声明适配器方法
	$.IFactory = $.IAdapter = function(mapping, proto, defualt, type) {
		if (arguments.length == 1 && mapping.mapping) {
			var op = mapping;
			return new Adapter(op.mapping, op.proto, op.setDefault, op.type);
		} else
			return new Adapter(mapping, proto, defualt, type);
	}

	/** ******************* handlers ************* */
	// 事件处理对象
	$.IHandler = function() {
		return {
			_list : [],
			// 添加委托事件
			add : function(fn) {
				this._list.push(fn);
				this.length = this._list.length;
			},
			// 执行委托事件,return false中断执行
			fire : function() {
				if (this._list.length) {
					var args = arguments, result;
					$.each(this._list, function(i, fn) {
								result = fn.apply(null, args);
								if (result === false)
									return false;
							});
					return result;
				}
			},
			// 依次作为this指针传递,第一个参数为开始传递对象,return false中断执行
			fireWithResult : function() {
				if (this._list.length) {
					var args = Array.prototype.slice.call(arguments, 0), obj = args.shift(), result;
					$.each(this._list, function(i, fn) {
								result = fn.apply(result || obj, args);
								if (result === false)
									return false;
							});
					return result;
				}
			}
		};
	}

	/** ******************* trigger ************* */
//	$.Trigger = $.IObject({
//		proto : {
//
//		}
//	});
	//触发器对象
	$.ITrigger = {
		initTrigger : function() {
			this._trMap = {};
			this._fnMap = {};
		},
		//初始化触发器(内置)
		_initTriggerOp : function(args) {
			var op, target = args[0];
			if (typeof(args[0]) == "string") {
				op = {
					name : target,
					fn : args[1],
					step : args[2]
				};
			} else
				op = target;
			//默认为后置触发
			op.step || (op.step = "after");
			return op;
		},
		//判断是否创建映射方法(内置)
		_checkTriggerMap : function(name) {
			var map = this.getTrigger(name);
			if (!map)
				map = this._trMap[name] = {};
			return map;
		},
		//添加触发器(内置)
		_addTrigger : function(map, fn, step) {
			var trigger = map[step];
			trigger || (trigger = map[step] = $.Callbacks());
			trigger.add(fn);
			return this;
		},
		//获取触发器
		getTrigger : function(name) {
			return this._trMap[name];
		},
		//手动添加触发器，（非自动绑定触发，须手动触发）
		addTrigger : function(name, fn, step) {
			var op = this._initTriggerOp(arguments), trMap = this._checkTriggerMap(op.name);
			return this._addTrigger(trMap, op.fn, op.step);
		},
		//绑定触发器（自动触发,会重写触发方法）
		bindTrigger : function(name, fn, step) {
			var op = this._initTriggerOp(arguments);
			name = op.name;
			this.addTrigger(op);

			var fnMap = this._fnMap[name];
			if (!fnMap) {
				this._fnMap[name] = this[name];
				this[name] = function() {
					var args = Array.prototype.slice.call(arguments, 0), trMap = this._trMap[name], result;

					if(this.fireTrigger(trMap.before, args) === false)
						return false;
					result = this.proxy(this._fnMap[name], args);
					if(args)
						args.result = result;
					else
						args = {result:result};
					this.fireTrigger(trMap.after, args);
					return result;
				}
			}
			return this;
		},
		//触发验证器
		fireTrigger : function(trigger, args, step) {
			if (typeof(trigger) == "string") {
				var map = this._trMap[trigger];
				trigger = map ? map[step || "after"] : null;
			}
			if(trigger)
				return trigger.fireWith(this, args);
		},
		//删除绑定的触发器
		unbindTrigger : function(name) {
			delete this._trMap[name];
		},
		//清除单个/所有触发器
		clearTrigger : function(name) {
			if (name)
				delete this._trMap[name];
			else
				this.initTrigger();
			return this;
		},
		extend:function(prop){
			var self = this;
			$.each(prop,function(name,fn){
				if(self._fnMap[name])
					self._fnMap[name] = fn;
				else
					self[name] = fn;
			})
			return self;
		}
	};
	
	/***************************	Dom模拟class对象	***************************/
	DomClass = {
		/** @description 获取属性对象
		 *  @param {JQDom} domObj 容器对象
		 *  @param {Dom} panel 容器Dom
		 *  @param {Object} prop 属性
		 *  @param {String} filter 过滤器
		 *  @param {Boolean} isChilds 是否是子对象
		 *  @return {JQDom} 
		 */
		getProp : function(domObj, panel, prop, filter, isChilds) {
			var props = domObj._domProps;
			props || (props = domObj._domProps = {});
			var dom = props[prop];
	        if (!dom)
	        {
	            props[prop] = dom = isChilds ?  panel.find(filter) : panel.children(filter);
	        }
	        return dom;
		},
		/** @description 清除所有缓存
		 *  @param {JQDom} domObj 容器对象
		 */
		clear:function(domObj){
			domObj._domProps = {};
		}
	}
})();
